import traceback

from appium import webdriver
from appium.webdriver.webdriver import WebDriver
from selenium.common import NoSuchElementException
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from appium_qiyeweixin.until.log_until import logger
from appium_qiyeweixin.until.until import get_yaml


class BasePage:
    _CAPABILITY = get_yaml("capability.yml")

    def __init__(self, driver: WebDriver = None):
        self.driver = driver

    def start_weixin(self):
        if not self.driver:
            self.driver = webdriver.Remote("http://localhost:4723/wd/hub", self._CAPABILITY)
            self.driver.implicitly_wait(10)
        else:
            self.driver.launch_app()

        from appium_qiyeweixin.page_object.message_page import MessagePage
        return MessagePage(self.driver)

    def quit(self):
        self.driver.quit()

    def do_find(self, by, located=None):
        return self.driver.find_element(*by) if not located else self.driver.find_element(by, located)

    def do_finds(self, by, located=None):
        return self.driver.find_elements(*by) if not located else self.driver.find_elements(by, located)

    def do_ele_click(self, by, located=None):
        element = self.do_find(by, located)
        element.click()

        return self

    def do_ele_send_keys(self, context, by, located=None):
        element = self.do_find(by, located)
        element.click()
        element.clear()
        element.send_keys(context)
        self.driver.find_element_by_image()
        return self

    # 向上滑动
    def do_swipe(self, by, located=None, num=3):
        for i in range(num):
            try:
                element = self.do_find(by, located)

                return element
            except Exception as e:
                window_size = self.driver.get_window_size()
                width = window_size.get('width')
                height = window_size.get('height')
                start_x = width / 2
                start_y = height * 0.8
                end_x = start_x
                end_y = height * 0.3
                duration = 2000
                self.driver.swipe(start_x, start_y, end_x, end_y, duration)
        if i == num - 1:
            logger.error(NoSuchElementException(f"循环获取元素{num}次， 但无法找到该元素，请重新尝试定位！"))
            logger.error(f"traceback.format_exc() ==> {traceback.format_exc()}")
            raise NoSuchElementException(f"循环获取元素{num}次， 但无法找到该元素，请重新尝试定位！")

    # 左右滑动
    def do_swipe_sliding_around(self, coordinate: dict, duration: int = 2000):
        """

        :param duration:
        :param coordinate: {start_x: [0-1), start_y:[0-1), end_x:[0-1), end_y:[0-1)}
        :return: self
        """
        window_size = self.driver.get_window_size()
        width = window_size.get('width')
        height = window_size.get('height')
        start_x = width * coordinate.get("start_x", 0)
        start_y = height * coordinate.get("start_y", 0)
        end_x = width * coordinate.get("end_x", 0)
        end_y = height * coordinate.get("end_y", 0)

        self.driver.swipe(start_x, start_y, end_x, end_y, duration)

        return self

    def element_until_visibility(self, by: tuple):
        return WebDriverWait(self.driver, 10).until(expected_conditions.visibility_of_element_located(by))
